/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lt.ntec.danblog.server.core.model.objectify;

import com.google.appengine.api.datastore.Entity;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Id;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.Transient;
import lt.ntec.danblog.server.core.model.Tag;
import lt.ntec.danblog.server.core.model.Taggable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Tadas
 */
class ObjectifyTag implements Tag, Comparable<Tag> {

    private static final Logger LOG =
            LoggerFactory.getLogger(ObjectifyTag.class);
    private String value;
    @Transient
    private Set<Taggable> parents = new HashSet<Taggable>();
    private Set<Key<Taggable>> parentKeys = new HashSet<Key<Taggable>>();
    @Id
    private Long id;
    
    private int parentCount;

    public ObjectifyTag() {
    }

    public ObjectifyTag(String value, Taggable parent) {
        this.value = value.toLowerCase();
        this.parents.add(parent);
        this.parentKeys.add(new Key<Taggable>(parent.getClass(), parent.getId()));
    }

    @Override
    public String getValue() {
        return value;
    }

    @Override
    public Set<? extends Taggable> getEntryList() {
        return parents;
    }

    @Override
    public void addParent(Taggable entity) {
        parentKeys.add(new Key<Taggable>(entity.getClass(), entity.getId()));
        parents.add(entity);
    }

    @Override
    public void removeParent(Taggable entity) {
        parentKeys.remove(new Key<Taggable>(entity.getClass(), entity.getId()));
        parents.remove(entity);
    }

    @Override
    public Long getId() {
        return id;
    }

    @Override
    public int compareTo(Tag o) {
        return o.getValue().compareTo(this.getValue()) * (-1);
    }
    
    @Override
    public int getParentCount() {
        return parentCount;
    }

    public Set<Key<Taggable>> getParentKeys() {
        return parentKeys;
    }

    public void setParentKeys(Set<Key<Taggable>> parentKeys) {
        this.parentKeys = parentKeys;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ObjectifyTag other = (ObjectifyTag) obj;
        if ((this.value == null) ? (other.value != null) : !this.value.
                toLowerCase().equals(other.value.toLowerCase())) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 19 * hash + (this.value != null ? this.value.hashCode() : 0);
        return hash;
    }
    
    public void addParentKeys(Set<Key<Taggable>> keys) {
        this.parentKeys.addAll(keys);
    }

    @PostLoad
    void load(Objectify ofy, Entity ent) {
        LOG.debug("applying proxies for " + getId());

        this.parents = ProxyFactory.getInstance().getParentListProxy(this);
    }

    @PrePersist
    void persist(Objectify ofy, Entity ent) {
        parentCount = parentKeys.size();
    }
    
    
}
